home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / USEFUL_C / OOPS.C < prev    next >
Text File  |  1990-04-28  |  4KB  |  207 lines

  1.  
  2. /*
  3.  *  oops.c
  4.  *
  5.  *  Copyright (c) 1989 Symantec Corporation.  All rights reserved.
  6.  *
  7.  */
  8.  
  9. #include "oops.h"
  10.  
  11. #ifdef DIRECT
  12. #define member        memberD
  13. #define sizeofobj    sizeofobjD
  14. #define bless        blessD
  15. #define __msg        __msgD
  16. #else
  17. #define INDIRECT
  18. #endif
  19.  
  20. void __msg(void);
  21.  
  22.  
  23. /*
  24.  *  new - allocate a new object
  25.  *
  26.  *  The new object is returned.  (This implementation initializes the
  27.  *  object to all-bits-zero, but it may be unwise to rely on this.)
  28.  *
  29.  *  This routine is for use with indirect classes.  There is no
  30.  *  corresponding facility for direct classes.
  31.  *
  32.  *  If an object is created other than by calling this routine, it
  33.  *  must be marked as belonging to its class by calling "bless" or
  34.  *  "blessD".  (Since allocation of direct objects is the programmer's
  35.  *  responsibility, "blessD" must always be called.)
  36.  *
  37.  */
  38.  
  39. #ifdef INDIRECT
  40. void *
  41. new(class)
  42. void *class;
  43. {
  44.     asm {
  45.         moveq    #0,d0
  46.         movea.l    class,a1
  47.         move.w    (a1),d0                ;  D0.L = class size
  48.         _NewHandle  CLEAR
  49.         move.l    a0,d0
  50.         beq.s    @1
  51.         suba.l    a5,a1                ;  A1.W = class ID
  52.         movea.l    (a0),a0                ;  <<indirect>>
  53.         move.w    a1,(a0)
  54. @1    }
  55. }
  56. #endif INDIRECT
  57.  
  58.  
  59. /*
  60.  *  delete - free an object
  61.  *
  62.  *  This routine is for use with indirect classes.  There is no
  63.  *  corresponding facility for direct classes.
  64.  *
  65.  */
  66.  
  67. #ifdef INDIRECT
  68. void
  69. delete(obj)
  70. void *obj;
  71. {
  72.     asm {
  73.         move.l    obj,d0
  74.         beq.s    @1
  75.         movea.l    d0,a0
  76.         _DisposHandle
  77. @1    }
  78. }
  79. #endif INDIRECT
  80.  
  81.  
  82. /*
  83.  *  member, memberD - test whether an object is a member of a class
  84.  *
  85.  *  A non-zero value is returned if the object's class, or any of its
  86.  *  ancestors, is equal to the given class.
  87.  *
  88.  *  "member" is for use only with indirect classes, and "memberD" is
  89.  *  for use only with direct classes.  Do not attempt to use either
  90.  *  function to test whether a direct object is a member of an indirect
  91.  *  class, or whether an indirect object is a member of a direct class.
  92.  *  (Of course, in these cases, the answer is "no"!)
  93.  *
  94.  */
  95.  
  96. short
  97. member(obj, class)
  98. void *obj, *class;
  99. {
  100.     asm {
  101.         move.l    class,d1
  102.         sub.l    a5,d1                ;  D1.W = target class ID
  103.         movea.l    obj,a1
  104. #ifdef INDIRECT
  105.         movea.l    (a1),a1                ;  <<indirect>>
  106. #endif INDIRECT
  107.         move.w    (a1),d0                ;  D0.W = class ID
  108. @1        cmp.w    d0,d1
  109.         beq.s    @2
  110.         lea        2(a5,d0.w),a1        ;  A1 ==> class record + 2
  111.         move.w    (a1)+,d0            ;  D0.W = #methods - 1
  112.         add.w    d0,d0
  113.         add.w    d0,d0
  114.         move.w    4(a1,d0.w),d0        ;  D0.W = superclass ID
  115.         bne.s    @1
  116. @2    }
  117. }
  118.  
  119. /****************************************************************************
  120.  sizeofobj, sizeofobjD     [90-04-28] SAX
  121.  
  122.      Use these procedures to get the size of a single class-object without
  123.      including the inherited variables.
  124.  ****************************************************************************/
  125.  
  126.  
  127. short
  128. sizeofobj(
  129.     void        *obj )
  130. {
  131.     asm {
  132.         movea.l    obj,a1
  133. #ifdef INDIRECT
  134.         movea.l    (a1),a1                ;  <<indirect>>
  135. #endif INDIRECT
  136.         move.w    (a1),d0                ;  D0.W = class ID
  137.         lea        0(a5,d0.w),a1        ;  A1 ==> class record
  138.         move.w    (a1)+,d1            ;  D1.W = sizeof class
  139.         move.w    (a1)+,d0            ;  D0.W = #methods - 1
  140.         add.w    d0,d0
  141.         add.w    d0,d0
  142.         move.w    4(a1,d0.w),d0        ;  D0.W = superclass ID
  143.         bne.s    @1                    ;  We do have a superclass
  144.         subq    #2,d1                ;  Adjust for class ID
  145.         bra.s    @2
  146. @1        lea        0(a5,d0.w),a1        ;  A1 ==> class record of super
  147.         move.w    (a1),d2                ;  D2.W = sizeof class of super
  148.         sub.w    d2,d1
  149. @2        move.w    d1,d0
  150.     }
  151. }
  152.  
  153.  
  154. /*
  155.  *  bless, blessD - mark an object as being of a particular class
  156.  *
  157.  *  If an object is created other than by "new", this routine must
  158.  *  be called to mark it as a member of its class.
  159.  *
  160.  *  Do not use this routine to change an object's class!
  161.  *
  162.  */
  163.  
  164. void
  165. bless(obj, class)
  166. void *obj, *class;
  167. {
  168.     asm {
  169.         move.l    class,d1
  170.         sub.l    a5,d1                ;  D1.W = class ID
  171.         movea.l    obj,a1
  172. #ifdef INDIRECT
  173.         movea.l    (a1),a1                ;  <<indirect>>
  174. #endif INDIRECT
  175.         move.w    d1,(a1)
  176.     }
  177. }
  178.  
  179.  
  180. /*
  181.  *  __msg, __msgD - message dispatcher
  182.  *
  183.  *  The dispatcher is called only from code generated by the compiler.
  184.  *
  185.  */
  186.  
  187. void
  188. __msg()
  189. {
  190.     asm {
  191.         movea.l    4(sp),a1
  192.         move.w    -(a1),d2            ;  D2.W = message ID
  193.         movea.l    8(sp),a1
  194. #ifdef INDIRECT
  195.         movea.l    (a1),a1                ;  <<indirect>>
  196. #endif INDIRECT
  197. @1        move.w    (a1),d0
  198.         lea        2(a5,d0.w),a1        ;  A1 ==> class record + 2
  199.         move.w    (a1)+,d0            ;  D0.W = #methods - 1
  200. @2        move.w    (a1)+,d1            ;  D1.W = method ID
  201.         cmp.w    (a1)+,d2
  202.         dbeq    d0,@2
  203.         bne.s    @1                    ;  not found - search superclass
  204.         lea        0(a5,d1.w),a0        ;  A0 ==> method
  205.     }
  206. }
  207.